﻿using WindowsFormsModel.BusinessObjects;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using WindowsFormsModel.DataTransferObjectMapper;
using WindowsFormsModel.ActionServiceReference;
using System;
using System.Net;
using System.IO;
using System.Runtime.Serialization.Json;

namespace WindowsFormsModel
{
    public class Model : IModel
    {
        #region statics

        private static ActionServiceClient Client { get; set; }
        private static string AccessToken { get; set; }
        private static string ClientTag { get; set; }
        private static string RestaurantID { get; set; }

        static Model()
        {
            //tạo một đối tượng proxy
            Client = new ActionServiceClient();

            //Lấy client tag từ file config
            ClientTag = ConfigurationManager.AppSettings.Get("ClientTag");

            //gán các dữ liệu để gửi lên server
            var request = PrepareRequest(new TokenRequest());

            var response = Client.GetToken(request);

            // Store access token for all subsequent service calls.
            AccessToken = response.AccessToken;
        }

        /// <summary>
        /// Để đưa dữ liệu lên được host cần requestId, ClientTag, và AccessToken
        /// </summary>
        /// <typeparam name="T">Kiểu request</typeparam>
        /// <param name="request">request</param>
        /// <returns>Trả về dữ liệu tương ứng</returns>
        private static T PrepareRequest<T>(T request) where T : RequestBase
        {
            request.RequestId = Guid.NewGuid().ToString();
            request.ClientTag = ClientTag;
            request.AccessToken = AccessToken;
            request.RestaurantID = RestaurantID;

            return request;
        }

        #endregion

        #region Login/Logout"

        public void Login(string userName, string password, string restaurantId)
        {
            RestaurantID = restaurantId;
            var request = PrepareRequest(new LoginRequest());

            request.UserName = userName;
            request.Password = password;


            var response = Client.Login(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("LoginRequest: RequestId và CorrectionId không trùng khớp !");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
        }

        #endregion

        #region UserGroups

        public UserGroupModel GetUserGroup(string userGroupId)
        {
            var request = PrepareRequest(new UserGroupRequest());
            request.LoadOptions = new string[] { "UserGroup" };
            request.Criteria = new UserGroupCriteria { UserGroupId = userGroupId };

            var response = Client.GetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCustomer: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.UserGroup);
        }

        public IList<UserGroupModel> GetUserGroups()
        {
            var request = PrepareRequest(new UserGroupRequest());

            request.LoadOptions = new string[] { "UserGroups", "NoImage" };

            var response = Client.GetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUserGroups: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            if (response.UserGroups != null && response.UserGroups.Count() > 0)
                return Mapper.FromDataTransferObjects(response.UserGroups);
            else
                return null;
        }

        public IList<UserGroupModel> GetUserGroupsByBranch()
        {
            var request = PrepareRequest(new UserGroupRequest());

            request.LoadOptions = new string[] { "UserGroupsByBranch" };

            var response = Client.GetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUserGroups: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            if (response.UserGroups != null && response.UserGroups.Count() > 0)
                return Mapper.FromDataTransferObjects(response.UserGroups);
            else
                return null;
        }

        #endregion

        #region UserGroup persistence

        public int AddUserGroup(UserGroupModel userGroup)
        {
            var request = PrepareRequest(new UserGroupRequest());
            request.Action = "Create";

            userGroup.RestaurantID = RestaurantID;
            request.UserGroup = Mapper.ToDataTransferObject(userGroup);

            var response = Client.SetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddUserGroup: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateUserGroup(UserGroupModel userGroup)
        {
            var request = PrepareRequest(new UserGroupRequest());
            request.Action = "Update";
            request.UserGroup = Mapper.ToDataTransferObject(userGroup);

            var response = Client.SetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateUserGroup: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteUserGroup(string userGroupId)
        {
            var request = PrepareRequest(new UserGroupRequest());
            request.Action = "Delete";
            request.Criteria = new UserGroupCriteria { UserGroupId = userGroupId };

            var response = Client.SetUserGroups(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteUserGroup: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Restaurants

        public IList<RestaurantModel> GetRestaurants()
        {
            var request = PrepareRequest(new RestaurantRequest());
            request.Criteria = new RestaurantCriteria();
            request.LoadOptions = new string[] { "Restaurants" };

            var response = Client.GetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurants: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Restaurants);
        }
        public IList<RestaurantModel> GetRestaurantsByPage(int currentPage)
        {
            var request = PrepareRequest(new RestaurantRequest());

            request.LoadOptions = new string[] { "Restaurants", "ByPage" };
            request.Criteria = new RestaurantCriteria { CurrentPage = currentPage };

            var response = Client.GetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Restaurants);
        }
        public int GetTotalPageFromRestaurant()
        {
            var request = PrepareRequest(new RestaurantRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurant: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public RestaurantModel GetRestaurant(string restaurantId)
        {
            var request = PrepareRequest(new RestaurantRequest());
            request.LoadOptions = new string[] { "Restaurant" };
            request.Criteria = new RestaurantCriteria { RestaurantId = restaurantId };

            var response = Client.GetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurant: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.Restaurant);
        }

        #endregion

        #region Restaurant persistence

        public int AddRestaurant(RestaurantModel restaurant)
        {
            var request = PrepareRequest(new RestaurantRequest());
            request.Action = "Create";

            request.Restaurant = Mapper.ToDataTransferObject(restaurant);

            var response = Client.SetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurant: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateRestaurant(RestaurantModel restaurant)
        {
            var request = PrepareRequest(new RestaurantRequest());
            request.Action = "Update";

            request.Restaurant = Mapper.ToDataTransferObject(restaurant);

            var response = Client.SetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateRestaurant: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteRestaurant(string restaurantId)
        {
            var request = PrepareRequest(new RestaurantRequest());
            request.Action = "Delete";
            request.Criteria = new RestaurantCriteria { RestaurantId = restaurantId };

            var response = Client.SetRestaurants(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurant: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region AccountingObjectCategories

        public AccountingObjectCategoryModel GetAccountingObjectCategory(string accountingObjectCategoryId)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());
            request.LoadOptions = new string[] { "AcountingObjectCategoryByBranch" };
            request.Criteria = new AccountingObjectCategoryCriteria { AccountingObjectCategoryID = accountingObjectCategoryId };

            var response = Client.GetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.AccountingObjectCategory);
        }

        public IList<AccountingObjectCategoryModel> GetAccountingObjectCategoriesByBranch(bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());

            request.LoadOptions = new string[] { "AcountingObjectCategoriesByBranch" };
            request.Criteria = new AccountingObjectCategoryCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };
            var response = Client.GetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectCategoriesByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjectCategories);
        }

        public IList<AccountingObjectCategoryModel> GetAccountingObjectCategoriesByBranchAndActive(bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());

            request.LoadOptions = new string[] { "AcountingObjectCategoriesByBranch", "Active" };
            request.Criteria = new AccountingObjectCategoryCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };
            var response = Client.GetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectCategoriesByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjectCategories);
        }

        #endregion

        #region AccountingObjectCategory persistence

        public int AddAccountingObjectCategory(AccountingObjectCategoryModel accountingObjectCategory)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());
            request.Action = "Create";

            accountingObjectCategory.RestaurantID = RestaurantID;
            request.AccountingObjectCategory = Mapper.ToDataTransferObject(accountingObjectCategory);

            var response = Client.SetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddAccountingObjectCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateAccountingObjectCategory(AccountingObjectCategoryModel accountingObjectCategory)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());
            request.Action = "Update";

            accountingObjectCategory.RestaurantID = RestaurantID;
            request.AccountingObjectCategory = Mapper.ToDataTransferObject(accountingObjectCategory);

            var response = Client.SetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateAccountingObjectCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteAccountingObjectCategory(string accountingObjectCategoryId)
        {
            var request = PrepareRequest(new AccountingObjectCategoryRequest());
            request.Action = "Delete";
            request.Criteria = new AccountingObjectCategoryCriteria { AccountingObjectCategoryID = accountingObjectCategoryId };

            var response = Client.SetAccountingObjectCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteAccountingObjectCategory: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region CountryRegions

        public IList<CountryRegionModel> GetCountryRegions()
        {
            var request = PrepareRequest(new CountryRegionRequest());

            request.LoadOptions = new string[] { "CountryRegions" };
            var response = Client.GetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCountryRegions: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.CountryRegions);
        }
        public CountryRegionModel GetCountryRegion(string countryRegionCode)
        {
            var request = PrepareRequest(new CountryRegionRequest());
            request.LoadOptions = new string[] { "CountryRegion" };
            request.Criteria = new CountryRegionCriteria { CountryRegionCode = countryRegionCode };

            var response = Client.GetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCountryRegion: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.CountryRegion);
        }
        public IList<CountryRegionModel> GetCountryRegionsActive()
        {
            var request = PrepareRequest(new CountryRegionRequest());

            request.LoadOptions = new string[] { "CountryRegions", "Active" };
            var response = Client.GetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCountryRegionsByIsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.CountryRegions);
        }
        public IList<CountryRegionModel> GetCountryRegionsByPage(int currentPage)
        {
            var request = PrepareRequest(new CountryRegionRequest());

            request.LoadOptions = new string[] { "CountryRegions", "ByPage" };
            request.Criteria = new CountryRegionCriteria { CurrentPage = currentPage };

            var response = Client.GetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCountryRegionsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.CountryRegions);
        }
        public int GetTotalPageFromCountryRegion()
        {
            var request = PrepareRequest(new DistrictRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistricts: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }

        #endregion

        #region CountryRegion persistence

        public int AddCountryRegion(CountryRegionModel countryRegion)
        {
            var request = PrepareRequest(new CountryRegionRequest());
            request.Action = "Create";

            request.CountryRegion = Mapper.ToDataTransferObject(countryRegion);

            var response = Client.SetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("CountryRegionModel: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateCountryRegion(CountryRegionModel countryRegion)
        {
            var request = PrepareRequest(new CountryRegionRequest());
            request.Action = "Update";

            request.CountryRegion = Mapper.ToDataTransferObject(countryRegion);

            var response = Client.SetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateCountryRegion: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteCountryRegion(string countryRegionCode)
        {
            var request = PrepareRequest(new CountryRegionRequest());
            request.Action = "Delete";
            request.Criteria = new CountryRegionCriteria { CountryRegionCode = countryRegionCode };

            var response = Client.SetCountryRegions(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteCountryRegion: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Districts

        public IList<DistrictModel> GetDistricts()
        {
            var request = PrepareRequest(new DistrictRequest());

            request.LoadOptions = new string[] { "Districts" };
            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistricts: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Districts);
        }
        public IList<DistrictModel> GetDistrictsByPage(int currentPage)
        {
            var request = PrepareRequest(new DistrictRequest());

            request.LoadOptions = new string[] { "Districts", "ByPage" };
            request.Criteria = new DistrictCriteria { CurrentPage = currentPage };

            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistricts: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Districts);
        }
        public int GetTotalPageFromDistrict()
        {
            var request = PrepareRequest(new DistrictRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistricts: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public DistrictModel GetDistrict(string districtCode)
        {
            var request = PrepareRequest(new DistrictRequest());
            request.LoadOptions = new string[] { "District" };
            request.Criteria = new DistrictCriteria { DistrictCode = districtCode };

            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistrict: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.District);
        }
        public IList<DistrictModel> GetDistrictsActive()
        {
            var request = PrepareRequest(new DistrictRequest());

            request.LoadOptions = new string[] { "Districts", "Active" };
            var response = Client.GetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDistrictsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Districts);
        }

        #endregion

        #region District persistence

        public int AddDistrict(DistrictModel district)
        {
            var request = PrepareRequest(new DistrictRequest());
            request.Action = "Create";

            request.District = Mapper.ToDataTransferObject(district);

            var response = Client.SetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddDistrict: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateDistrict(DistrictModel district)
        {
            var request = PrepareRequest(new DistrictRequest());
            request.Action = "Update";

            request.District = Mapper.ToDataTransferObject(district);

            var response = Client.SetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateDistrict: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteDistrict(string districtCode)
        {
            var request = PrepareRequest(new DistrictRequest());
            request.Action = "Delete";
            request.Criteria = new DistrictCriteria { DistrictCode = districtCode };

            var response = Client.SetDistricts(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteDistrict: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Provinces

        public IList<ProvinceModel> GetProvinces()
        {
            var request = PrepareRequest(new ProvinceRequest());

            request.LoadOptions = new string[] { "Provinces" };
            var response = Client.GetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetProvinces: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Provinces);
        }
        public ProvinceModel GetProvince(string ProvinceCode)
        {
            var request = PrepareRequest(new ProvinceRequest());
            request.LoadOptions = new string[] { "Province" };
            request.Criteria = new ProvinceCriteria { ProvinceCode = ProvinceCode };

            var response = Client.GetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetProvince: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.Province);
        }
        public IList<ProvinceModel> GetProvincesActive()
        {
            var request = PrepareRequest(new ProvinceRequest());

            request.LoadOptions = new string[] { "Provinces", "Active" };
            var response = Client.GetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetProvincesActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Provinces);
        }
        public int GetTotalPageFromProvince()
        {
            var request = PrepareRequest(new ProvinceRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromProvince: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public IList<ProvinceModel> GetProvincesByPage(int currentPage)
        {
            var request = PrepareRequest(new ProvinceRequest());

            request.LoadOptions = new string[] { "Provinces", "ByPage" };
            request.Criteria = new ProvinceCriteria { CurrentPage = currentPage };

            var response = Client.GetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetProvincesByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Provinces);
        }

        #endregion

        #region Province persistence

        public int AddProvince(ProvinceModel Province)
        {
            var request = PrepareRequest(new ProvinceRequest());
            request.Action = "Create";

            request.Province = Mapper.ToDataTransferObject(Province);

            var response = Client.SetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddProvince: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateProvince(ProvinceModel Province)
        {
            var request = PrepareRequest(new ProvinceRequest());
            request.Action = "Update";

            request.Province = Mapper.ToDataTransferObject(Province);

            var response = Client.SetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateProvince: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteProvince(string ProvinceCode)
        {
            var request = PrepareRequest(new ProvinceRequest());
            request.Action = "Delete";
            request.Criteria = new ProvinceCriteria { ProvinceCode = ProvinceCode };

            var response = Client.SetProvinces(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteProvince: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region AccountingObjects

        public IList<AccountingObjectModel> GetAccountingObjectsByPageAndBranch(int currentPage)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "AccountingObjects", "ByPageAndBranch" };
            request.Criteria = new AccountingObjectCriteria { CurrentPage = currentPage };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjects);
        }
        public IList<AccountingObjectModel> GetAccountingObjectsByPageAndBranch(int currentPage, bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "AccountingObjects", "ByPageAndBranch" };
            request.Criteria = new AccountingObjectCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjects);
        }
        public IList<AccountingObjectModel> GetAccountingObjectsByPageAndBranch(int currentPage, string accountingObjectCategoryId)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "AccountingObjects", "ByPageAndBranch", "ByCategory" };
            request.Criteria = new AccountingObjectCriteria { CurrentPage = currentPage, AccountingObjectCategoryId = accountingObjectCategoryId };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectsByPageAndBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjects);
        }
        public IList<AccountingObjectModel> GetAccountingObjectsActiveByBranch(bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "AccountingObjects", "ActiveByBranch" };
            request.Criteria = new AccountingObjectCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObjectsActiveByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.AccountingObjects);
        }
        public int GetTotalPageFromAccountingObject(bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            request.Criteria = new AccountingObjectCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };
            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromAccountingObject: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }
        public int GetTotalPageFromAccountingObjectByBranch(bool isCustomer, bool isVendor, bool isEmployee)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };
            request.Criteria = new AccountingObjectCriteria { IsCustomer = isCustomer, IsVendor = isVendor, IsEmployee = isEmployee };
            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromAccountingObject: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }
        public int GetTotalPageFromAccountingObjectByCategory(string accountingObjectCategoryId)
        {
            var request = PrepareRequest(new AccountingObjectRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByCategory" };
            request.Criteria = new AccountingObjectCriteria { AccountingObjectCategoryId = accountingObjectCategoryId };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromAccountingObjectByCategory: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public AccountingObjectModel GetAccountingObject(string accountingObjectId)
        {
            var request = PrepareRequest(new AccountingObjectRequest());
            request.LoadOptions = new string[] { "AccountingObject", "ByBranch" };
            request.Criteria = new AccountingObjectCriteria { AccountingObjectId = accountingObjectId };

            var response = Client.GetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAccountingObject: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.AccountingObject);
        }

        #endregion

        #region AccountingObject persistence

        public int AddAccountingObject(AccountingObjectModel accountingObject)
        {
            var request = PrepareRequest(new AccountingObjectRequest());
            accountingObject.RestaurantId = RestaurantID;

            request.Action = "Create";
            request.AccountingObject = Mapper.ToDataTransferObject(accountingObject);

            var response = Client.SetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddAccountingObject: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateAccountingObject(AccountingObjectModel AccountingObject)
        {
            var request = PrepareRequest(new AccountingObjectRequest());
            request.Action = "Update";

            request.AccountingObject = Mapper.ToDataTransferObject(AccountingObject);

            var response = Client.SetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateAccountingObject: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteAccountingObject(string accountingObjectId)
        {
            var request = PrepareRequest(new AccountingObjectRequest());
            request.Action = "Delete";
            request.Criteria = new AccountingObjectCriteria { AccountingObjectId = accountingObjectId };

            var response = Client.SetAccountingObjects(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteAccountingObject: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region InventoryItemCategories

        public InventoryItemCategoryModel GetInventoryItemCategory(string inventoryCategoryId)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());
            request.LoadOptions = new string[] { "InventoryItemCategoryByBranch" };
            request.Criteria = new InventoryItemCategoryCriteria { InventoryCategoryID = inventoryCategoryId };

            var response = Client.GetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.InventoryItemCategory);
        }
        public IList<InventoryItemCategoryModel> GetInventoryItemCategoriesByBranch(bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());

            request.LoadOptions = new string[] { "InventoryItemCategoriesByBranch" };
            request.Criteria = new InventoryItemCategoryCriteria { IsMaterial = isMaterial };
            var response = Client.GetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemCategoriesByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InventoryItemCategories);
        }
        public IList<InventoryItemCategoryModel> GetInventoryItemCategoriesByBranchAndActive(bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());

            request.LoadOptions = new string[] { "InventoryItemCategoriesByBranch", "Active" };
            request.Criteria = new InventoryItemCategoryCriteria { IsMaterial = isMaterial };
            var response = Client.GetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemCategoriesByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InventoryItemCategories);
        }

        #endregion

        #region InventoryItemCategory persistence

        public int AddInventoryItemCategory(InventoryItemCategoryModel inventoryItemCategory)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());
            request.Action = "Create";

            inventoryItemCategory.RestaurantID = RestaurantID;
            request.InventoryItemCategory = Mapper.ToDataTransferObject(inventoryItemCategory);

            var response = Client.SetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddInventoryItemCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateInventoryItemCategory(InventoryItemCategoryModel inventoryItemCategory)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());
            request.Action = "Update";

            inventoryItemCategory.RestaurantID = RestaurantID;
            request.InventoryItemCategory = Mapper.ToDataTransferObject(inventoryItemCategory);

            var response = Client.SetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateInventoryItemCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteInventoryItemCategory(string inventoryItemCategoryId)
        {
            var request = PrepareRequest(new InventoryItemCategoryRequest());
            request.Action = "Delete";
            request.Criteria = new InventoryItemCategoryCriteria { InventoryCategoryID = inventoryItemCategoryId };

            var response = Client.SetInventoryItemCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteInventoryItemCategory: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Stocks

        public StockModel GetStock(string stockId)
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "Stock" };
            request.Criteria = new StockCriteria { StockID = stockId };

            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetStocksByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObject(response.Stock);
        }
        public IList<StockModel> GetStocksByBranch()
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "Stocks", "ByBranch" };
            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetStocksByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Stocks);
        }
        public IList<StockModel> GetStocksByPageAndBranch(int currentPage)
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "Stocks", "ByPageAndBranch" };
            request.Criteria = new StockCriteria { CurrentPage = currentPage };

            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetStocksByPageAndBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Stocks);
        }
        public int GetTotalPageFromStockByBranch()
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };
            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromStockByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public IList<StockModel> GetStocksActive()
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "Stocks", "Active" };
            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetStocksActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Stocks);
        }
        public IList<StockModel> GetStocksActiveByBranch()
        {
            var request = PrepareRequest(new StockRequest());

            request.LoadOptions = new string[] { "Stocks", "ActiveByBranch" };
            var response = Client.GetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetStocksActiveByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Stocks);
        }

        #endregion

        #region Stock persistence

        public int AddStock(StockModel stock)
        {
            var request = PrepareRequest(new StockRequest());
            request.Action = "Create";

            stock.RestaurantID = RestaurantID;
            request.Stock = Mapper.ToDataTransferObject(stock);

            var response = Client.SetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddStock: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateStock(StockModel stock)
        {
            var request = PrepareRequest(new StockRequest());
            request.Action = "Update";

            stock.RestaurantID = RestaurantID;
            request.Stock = Mapper.ToDataTransferObject(stock);

            var response = Client.SetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateStock: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.RowsAffected;
        }
        public int DeleteStock(string stockId)
        {
            var request = PrepareRequest(new StockRequest());
            request.Action = "Delete";
            request.Criteria = new StockCriteria { StockID = stockId };

            var response = Client.SetStocks(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteStock: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.RowsAffected;
        }

        #endregion

        #region Units

        public IList<UnitModel> GetUnits()
        {
            var request = PrepareRequest(new UnitsRequest());

            request.LoadOptions = new string[] { "Units" };
            var response = Client.GetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUnits: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Units);
        }
        public IList<UnitModel> GetUnitsByPage(int currentPage)
        {
            var request = PrepareRequest(new UnitsRequest());

            request.LoadOptions = new string[] { "Units", "ByPage" };
            request.Criteria = new UnitsCriteria { CurrentPage = currentPage };

            var response = Client.GetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUnitsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Units);
        }
        public int GetTotalPageFromUnit()
        {
            var request = PrepareRequest(new UnitsRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromUnit: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public UnitModel GetUnit(string unitId)
        {
            var request = PrepareRequest(new UnitsRequest());
            request.LoadOptions = new string[] { "Unit" };
            request.Criteria = new UnitsCriteria { UnitID = unitId };

            var response = Client.GetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUnit: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.Unit);
        }
        public IList<UnitModel> GetUnitsActive()
        {
            var request = PrepareRequest(new UnitsRequest());

            request.LoadOptions = new string[] { "Units", "Active" };
            var response = Client.GetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetUnitsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Units);
        }

        #endregion

        #region Unit persistence

        public int AddUnit(UnitModel unit)
        {
            var request = PrepareRequest(new UnitsRequest());
            unit.RestaurantID = RestaurantID;
            request.Action = "Create";

            request.Unit = Mapper.ToDataTransferObject(unit);

            var response = Client.SetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddUnit: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateUnit(UnitModel unit)
        {
            var request = PrepareRequest(new UnitsRequest());
            request.Action = "Update";

            request.Unit = Mapper.ToDataTransferObject(unit);

            var response = Client.SetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateUnit: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteUnit(string unitId)
        {
            var request = PrepareRequest(new UnitsRequest());
            request.Action = "Delete";
            request.Criteria = new UnitsCriteria { UnitID = unitId };

            var response = Client.SetUnits(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteUnit: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region InventoryItems

        public IList<InventoryItemModel> GetInventoryItemsByPage(int currentPage, bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems", "ByPage" };
            request.Criteria = new InventoryItemCriteria { CurrentPage = currentPage, IsMaterial = isMaterial };

            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public IList<InventoryItemModel> GetInventoryItemsByPageAndBranch(int currentPage, bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems", "ByPageAndBranch" };
            request.Criteria = new InventoryItemCriteria { CurrentPage = currentPage, IsMaterial = isMaterial };

            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public IList<InventoryItemModel> GetInventoryItems()
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems" };
            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItems: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public int GetTotalPageFromInventoryItem(bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            request.Criteria = new InventoryItemCriteria { IsMaterial = isMaterial };
            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromInventoryItem: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public InventoryItemModel GetInventoryItem(string inventoryItemId)
        {
            var request = PrepareRequest(new InventoryItemRequest());
            request.LoadOptions = new string[] { "InventoryItem" };
            request.Criteria = new InventoryItemCriteria { InventoryItemID = inventoryItemId };

            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItem: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.InventoryItem);
        }
        public IList<InventoryItemModel> GetInventoryItemsActive(bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems", "Active" };
            request.Criteria = new InventoryItemCriteria { IsMaterial = isMaterial, IsActive = true };
            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public IList<InventoryItemModel> GetInventoryItemsActiveByBranch(bool isMaterial)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems", "ActiveByBranch" };
            request.Criteria = new InventoryItemCriteria { IsMaterial = isMaterial, IsActive = true };
            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public IList<InventoryItemModel> GetInventoryItemsByPageAndCategory(int currentPage, string inventoryCategoryId)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "InventoryItems", "ByPageAndCategory" };
            request.Criteria = new InventoryItemCriteria { CurrentPage = currentPage, InventoryCategoryID = inventoryCategoryId };

            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInventoryItemsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InventoryItems);
        }
        public int GetTotalPageFromInventoryItemByCategory(string inventoryCategoryId)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByCategory" };
            request.Criteria = new InventoryItemCriteria { InventoryCategoryID = inventoryCategoryId };

            var response = Client.GetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromInventoryItemByCategory: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }

        #endregion

        #region InventoryItem persistence

        public int AddInventoryItem(InventoryItemModel inventoryItem)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.Action = "Create";
            inventoryItem.RestaurantId = RestaurantID;
            request.InventoryItem = Mapper.ToDataTransferObject(inventoryItem);

            var response = Client.SetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddInventoryItem: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateInventoryItem(InventoryItemModel inventoryItem)
        {
            var request = PrepareRequest(new InventoryItemRequest());

            request.Action = "Update";
            request.InventoryItem = Mapper.ToDataTransferObject(inventoryItem);

            var response = Client.SetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateInventoryItem: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteInventoryItem(string inventoryItemId)
        {
            var request = PrepareRequest(new InventoryItemRequest());
            request.Action = "Delete";
            request.Criteria = new InventoryItemCriteria { InventoryItemID = inventoryItemId };

            var response = Client.SetInventoryItems(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteInventoryItem: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region RestaurantAreas

        public IList<RestaurantAreaModel> GetRestaurantAreas()
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.Criteria = new RestaurantAreaCriteria();
            request.LoadOptions = new string[] { "RestaurantAreas" };

            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantAreas: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.RestaurantAreas);
        }
        public IList<RestaurantAreaModel> GetRestaurantAreasByBranch()
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.Criteria = new RestaurantAreaCriteria();
            request.LoadOptions = new string[] { "RestaurantAreas", "ByBranch" };

            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantAreas: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.RestaurantAreas);
        }
        public IList<RestaurantAreaModel> GetRestaurantAreasByPageAndBranch(int currentPage)
        {
            var request = PrepareRequest(new RestaurantAreaRequest());

            request.LoadOptions = new string[] { "RestaurantAreas", "ByPageAndBranch" };
            request.Criteria = new RestaurantAreaCriteria { CurrentPage = currentPage };

            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantAreasByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantAreas);
        }
        public int GetTotalPageFromRestaurantAreaByBranch()
        {
            var request = PrepareRequest(new RestaurantAreaRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };
            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantArea: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public RestaurantAreaModel GetRestaurantArea(string restaurantAreaId)
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.LoadOptions = new string[] { "RestaurantArea" };
            request.Criteria = new RestaurantAreaCriteria { RestaurantAreaID = restaurantAreaId };

            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantArea: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.RestaurantArea);
        }
        public IList<RestaurantAreaModel> GetRestaurantAreasActiveByBranch()
        {
            var request = PrepareRequest(new RestaurantAreaRequest());

            request.LoadOptions = new string[] { "RestaurantAreas", "ActiveByBranch" };

            var response = Client.GetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantAreasByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantAreas);
        }

        #endregion

        #region RestaurantArea persistence

        public int AddRestaurantArea(RestaurantAreaModel restaurantArea)
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.Action = "Create";
            restaurantArea.RestaurantID = RestaurantID;
            request.RestaurantArea = Mapper.ToDataTransferObject(restaurantArea);

            var response = Client.SetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurantArea: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateRestaurantArea(RestaurantAreaModel restaurantArea)
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.Action = "Update";

            request.RestaurantArea = Mapper.ToDataTransferObject(restaurantArea);

            var response = Client.SetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateRestaurantArea: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteRestaurantArea(string restaurantAreaId)
        {
            var request = PrepareRequest(new RestaurantAreaRequest());
            request.Action = "Delete";
            request.Criteria = new RestaurantAreaCriteria { RestaurantAreaID = restaurantAreaId };

            var response = Client.SetRestaurantAreas(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurantArea: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region RestaurantTables

        public IList<RestaurantTableModel> GetRestaurantTables()
        {
            var request = PrepareRequest(new RestaurantTableRequest());
            request.Criteria = new RestaurantTableCriteria();
            request.LoadOptions = new string[] { "RestaurantTables" };

            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantTables: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.RestaurantTables);
        }
        public IList<RestaurantTableModel> GetRestaurantTablesByPageAndBranch(int currentPage)
        {
            var request = PrepareRequest(new RestaurantTableRequest());

            request.LoadOptions = new string[] { "RestaurantTables", "ByPageAndBranch" };
            request.Criteria = new RestaurantTableCriteria { CurrentPage = currentPage };

            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantTablesByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantTables);
        }
        public IList<RestaurantTableModel> GetRestaurantTablesByPageAndArea(int currentPage, string restaurantAreaId)
        {
            var request = PrepareRequest(new RestaurantTableRequest());

            request.LoadOptions = new string[] { "RestaurantTables", "ByPageAndAera" };
            request.Criteria = new RestaurantTableCriteria { CurrentPage = currentPage, RestaurantAreaID = restaurantAreaId };

            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantTablesByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantTables);
        }
        public int GetTotalPageFromRestaurantTableByBranch()
        {
            var request = PrepareRequest(new RestaurantTableRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };
            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantTable: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public int GetTotalPageFromRestaurantTableByBranchAndAera(string restaurantAeraId)
        {
            var request = PrepareRequest(new RestaurantTableRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByArea" };
            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantTableByBranchAndArea: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public RestaurantTableModel GetRestaurantTable(string restaurantTableId)
        {
            var request = PrepareRequest(new RestaurantTableRequest());
            request.LoadOptions = new string[] { "RestaurantTable" };
            request.Criteria = new RestaurantTableCriteria { RestaurantTableID = restaurantTableId };

            var response = Client.GetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantTable: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.RestaurantTable);
        }

        #endregion

        #region RestaurantTable persistence

        public int AddRestaurantTable(RestaurantTableModel restaurantArea)
        {
            var request = PrepareRequest(new RestaurantTableRequest());
            request.Action = "Create";
            restaurantArea.RestaurantID = RestaurantID;
            request.RestaurantTable = Mapper.ToDataTransferObject(restaurantArea);

            var response = Client.SetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurantTable: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateRestaurantTable(RestaurantTableModel restaurantArea)
        {
            var request = PrepareRequest(new RestaurantTableRequest());
            request.Action = "Update";

            request.RestaurantTable = Mapper.ToDataTransferObject(restaurantArea);

            var response = Client.SetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateRestaurantTable: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteRestaurantTable(string restaurantTableId)
        {
            var request = PrepareRequest(new RestaurantTableRequest());
            request.Action = "Delete";
            request.Criteria = new RestaurantTableCriteria { RestaurantTableID = restaurantTableId };

            var response = Client.SetRestaurantTables(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurantTable: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region RestaurantMenuCategory

        public RestaurantMenuCategoryModel GetRestaurantMenuCategory(string menuCategoryId)
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());
            request.LoadOptions = new string[] { "RestaurantMenuCategory" };
            request.Criteria = new RestaurantMenuCategoryCriteria { MenuCategoryID = menuCategoryId };

            var response = Client.GetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("RestaurantMenuCategoryModel: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.RestaurantMenuCategory);
        }
        public IList<RestaurantMenuCategoryModel> GetRestaurantMenuCategoriesByBranch()
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());

            request.LoadOptions = new string[] { "RestaurantMenuCategories", "ByBranch" };

            var response = Client.GetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenuCategoriesByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenuCategories);
        }
        public IList<RestaurantMenuCategoryModel> GetRestaurantMenuCategoriesActiveByBranch()
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());

            request.LoadOptions = new string[] { "RestaurantMenuCategories", "ActiveByBranch" };
            var response = Client.GetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenuCategoriesActiveByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenuCategories);

        }

        #endregion

        #region RestaurantMenuCategory persistence

        public int AddRestaurantMenuCategory(RestaurantMenuCategoryModel restaurantMenuCategory)
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());
            request.Action = "Create";
            restaurantMenuCategory.RestaurantID = RestaurantID;
            request.RestaurantMenuCategory = Mapper.ToDataTransferObject(restaurantMenuCategory);

            var response = Client.SetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurantMenuCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateRestaurantMenuCategory(RestaurantMenuCategoryModel restaurantMenuCategory)
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());
            request.Action = "Update";
            restaurantMenuCategory.RestaurantID = RestaurantID;
            request.RestaurantMenuCategory = Mapper.ToDataTransferObject(restaurantMenuCategory);

            var response = Client.SetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurantMenuCategory: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteRestaurantMenuCategory(string restaurantMenuCategoryId)
        {
            var request = PrepareRequest(new RestaurantMenuCategoryRequest());
            request.Action = "Delete";
            request.Criteria = new RestaurantMenuCategoryCriteria { MenuCategoryID = restaurantMenuCategoryId };

            var response = Client.SetRestaurantMenuCategories(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurantMenuCategory: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region RestaurantMenu

        private byte[] GetMenuImage(string menuId)
        {
            string url = ConfigurationManager.AppSettings["ImageServiceUrl"];
            string requestUrl = string.Format("{0}/GetRestaurantMenu/{1}", url, menuId);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);

            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                using (Stream stream = response.GetResponseStream())
                {
                    byte[] buffer = new byte[32768];
                    MemoryStream ms = new MemoryStream();
                    int bytesRead, totalBytesRead = 0;
                    do
                    {
                        bytesRead = stream.Read(buffer, 0, buffer.Length);
                        totalBytesRead += bytesRead;

                        ms.Write(buffer, 0, bytesRead);
                    } while (bytesRead > 0);

                    ms.Position = 0;
                    return ms.ToArray();
                }
            }
        }
        public IList<RestaurantMenuModel> GetRestaurantMenusPagedByBranch(int currentPage)
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "RestaurantMenus", "ByPageAndBranch" };
            request.Criteria = new RestaurantMenuCriteria { CurrentPage = currentPage };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenusPagedAndBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenus);
        }
        public IList<RestaurantMenuModel> GetRestaurantMenusPagedByCategory(int currentPage, string menuCategoryId)
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "RestaurantMenus", "ByPageAndCategory" };
            request.Criteria = new RestaurantMenuCriteria { CurrentPage = currentPage, MenuCategoryID = menuCategoryId };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenusPagedAndBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenus);
        }
        public IList<RestaurantMenuModel> GetRestaurantMenusActiveByBranch()
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "RestaurantMenus", "ActiveByBranch" };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenusActiveByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenus);
        }
        public int GetTotalPageFromRestaurantMenu()
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantMenu: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }
        public int GetTotalPageFromRestaurantMenuByCategory(string menuCategoryId)
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByCategory" };
            request.Criteria = new RestaurantMenuCriteria { MenuCategoryID = menuCategoryId };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantMenu: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }
        public RestaurantMenuModel GetRestaurantMenu(string menudId)
        {
            var request = PrepareRequest(new RestaurantMenuRequest());

            request.LoadOptions = new string[] { "RestaurantMenu" };
            request.Criteria = new RestaurantMenuCriteria { MenuID = menudId };

            var response = Client.GetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantMenu: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            response.RestaurantMenu.MenuImage = GetMenuImage(menudId);

            return Mapper.FromDataTransferObject(response.RestaurantMenu);
        }

        #endregion

        #region RestaurantMenu persistence

        public void AddRestaurantMenu(RestaurantMenuModel restaurantMenu)
        {
            try
            {
                string url = ConfigurationManager.AppSettings["ImageServiceUrl"];
                if ((restaurantMenu.Description == null) || (restaurantMenu.Description == ""))
                    restaurantMenu.Description = "null";

                string requestUrl = string.Format("{0}/SetRestaurantMenus/{1}/{2}/{3}/{4}/{5}/{6}/{7}/{8}/{9}/{10}/{11}",
                                                            url,
                                                            "Create",
                                                            "null",
                                                            restaurantMenu.MenuCode,
                                                            restaurantMenu.MenuName,
                                                            restaurantMenu.Description,
                                                            restaurantMenu.UnitID,
                                                            restaurantMenu.SalesPrice.ToString(),
                                                            restaurantMenu.IsActive.ToString(),
                                                            restaurantMenu.IsNorm.ToString(),
                                                            RestaurantID,
                                                            restaurantMenu.MenuCategoryID);

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
                request.Method = "POST";
                request.ContentType = "text/plain";

                request.ContentLength = restaurantMenu.MenuImage.Length;

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(restaurantMenu.MenuImage, 0, restaurantMenu.MenuImage.Length);
                    requestStream.Close();
                }

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(RestaurantMenuResponseModel));
                        RestaurantMenuResponseModel restaurantMenuResponse = (RestaurantMenuResponseModel)dcs.ReadObject(stream);
                        if (restaurantMenuResponse.ErrorCode != 0)
                            throw new ApplicationException(restaurantMenuResponse.Message);
                    }
                }
            }
            catch (Exception ex) { throw new ApplicationException(ex.Message); }
        }
        public void UpdateRestaurantMenu(RestaurantMenuModel restaurantMenu)
        {
            try
            {
                string url = ConfigurationManager.AppSettings["ImageServiceUrl"];
                if (restaurantMenu.Description == null)
                    restaurantMenu.Description = "null";

                string requestUrl = string.Format("{0}/SetRestaurantMenus/{1}/{2}/{3}/{4}/{5}/{6}/{7}/{8}/{9}/{10}/{11}",
                                                            url,
                                                            "Update",
                                                            restaurantMenu.MenuID,
                                                            restaurantMenu.MenuCode,
                                                            restaurantMenu.MenuName,
                                                            restaurantMenu.Description,
                                                            restaurantMenu.UnitID,
                                                            restaurantMenu.SalesPrice.ToString(),
                                                            restaurantMenu.IsActive.ToString(),
                                                            restaurantMenu.IsNorm.ToString(),
                                                            RestaurantID,
                                                            restaurantMenu.MenuCategoryID);

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
                request.Method = "POST";
                request.ContentType = "text/plain";

                request.ContentLength = restaurantMenu.MenuImage.Length;

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(restaurantMenu.MenuImage, 0, restaurantMenu.MenuImage.Length);
                    requestStream.Close();
                }

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(RestaurantMenuResponseModel));
                        RestaurantMenuResponseModel restaurantMenuResponse = (RestaurantMenuResponseModel)dcs.ReadObject(stream);
                        if (restaurantMenuResponse.ErrorCode != 0)
                            throw new ApplicationException(restaurantMenuResponse.Message);
                    }
                }
            }
            catch (Exception ex) { throw new ApplicationException(ex.Message); }
        }
        public int DeleteRestaurantMenu(string menudId)
        {
            var request = PrepareRequest(new RestaurantMenuRequest());
            request.Action = "Delete";
            request.Criteria = new RestaurantMenuCriteria { MenuID = menudId };

            var response = Client.SetRestaurantMenus(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurantMenu: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region RestaurantMenuNorm

        public RestaurantMenuNormModel GetRestaurantMenuNorm(string menuNormId)
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());

            request.LoadOptions = new string[] { "RestaurantMenuNorm", "RestaurantMenuNormDetails" };
            request.Criteria = new RestaurantMenuNormCriteria { MenuNormID = menuNormId };

            var response = Client.GetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenuNorm: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObject(response.RestaurantMenuNorm, response.RestaurantMenuNormDetails);
        }
        public IList<RestaurantMenuNormModel> GetRestaurantMenuNormsPageByBranch(int currentPage)
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());

            request.LoadOptions = new string[] { "RestaurantMenuNorms", "ByPageAndBranch" };
            request.Criteria = new RestaurantMenuNormCriteria { CurrentPage = currentPage };

            var response = Client.GetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetRestaurantMenuNormsPageByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.RestaurantMenuNorms);
        }
        public int GetTotalPageFromRestaurantMenuNormByBranch()
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch" };

            var response = Client.GetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromRestaurantMenuNormByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }

        #endregion

        #region RestaurantMenuNorm persistence

        public int AddRestaurantMenuNorm(RestaurantMenuNormModel restaurantMenuNorm)
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());
            request.LoadOptions = new string[] { "RestaurantMenuNormDetails" };
            request.Action = "Create";

            restaurantMenuNorm.RestaurantID = RestaurantID;
            restaurantMenuNorm.MenuNormID = Guid.NewGuid().ToString();

            for (int i = 0; i < restaurantMenuNorm.RestaurantMenuNormDetails.Count; i++)
            {
                restaurantMenuNorm.RestaurantMenuNormDetails[i].MenuNormID = restaurantMenuNorm.MenuNormID;
                restaurantMenuNorm.RestaurantMenuNormDetails[i].RestaurantID = restaurantMenuNorm.RestaurantID;
            }

            request.Criteria = new RestaurantMenuNormCriteria { RestaurantMenuNormDetails = Mapper.FromDataTransferObjects(restaurantMenuNorm.RestaurantMenuNormDetails) };
            request.RestaurantMenuNorm = Mapper.ToDataTransferObject(restaurantMenuNorm);

            var response = Client.SetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddRestaurantMenuNorm: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateRestaurantMenuNorm(RestaurantMenuNormModel restaurantMenuNorm)
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());
            request.LoadOptions = new string[] { "RestaurantMenuNormDetails" };
            request.Action = "Update";

            for (int i = 0; i < restaurantMenuNorm.RestaurantMenuNormDetails.Count; i++)
            {
                restaurantMenuNorm.RestaurantMenuNormDetails[i].MenuNormID = restaurantMenuNorm.MenuNormID;
                restaurantMenuNorm.RestaurantMenuNormDetails[i].RestaurantID = restaurantMenuNorm.RestaurantID;
            }

            request.Criteria = new RestaurantMenuNormCriteria { RestaurantMenuNormDetails = Mapper.FromDataTransferObjects(restaurantMenuNorm.RestaurantMenuNormDetails) };
            request.RestaurantMenuNorm = Mapper.ToDataTransferObject(restaurantMenuNorm);

            var response = Client.SetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateRestaurantMenuNorm: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteRestaurantMenuNorm(string menudNormId)
        {
            var request = PrepareRequest(new RestaurantMenuNormRequest());
            request.LoadOptions = new string[] { "RestaurantMenuNormDetails" };
            request.Action = "Delete";
            request.Criteria = new RestaurantMenuNormCriteria { MenuNormID = menudNormId };

            var response = Client.SetRestaurantMenuNorms(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteRestaurantMenuNorm: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Currencies

        public IList<CurrencyModel> GetCurrencies()
        {
            var request = PrepareRequest(new CurrencyRequest());

            request.LoadOptions = new string[] { "Currencies" };
            var response = Client.GetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCurrencies: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Currencies);
        }
        public IList<CurrencyModel> GetCurrenciesActive()
        {
            var request = PrepareRequest(new CurrencyRequest());

            request.LoadOptions = new string[] { "Currencies", "Active" };
            var response = Client.GetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCurrenciesActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Currencies);
        }
        public IList<CurrencyModel> GetCurrenciesByPage(int currentPage)
        {
            var request = PrepareRequest(new CurrencyRequest());

            request.LoadOptions = new string[] { "Currencies", "ByPage" };
            request.Criteria = new CurrencyCriteria { CurrentPage = currentPage };

            var response = Client.GetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCurrenciesByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.Currencies);
        }
        public CurrencyModel GetCurrency(string currencyId)
        {
            var request = PrepareRequest(new CurrencyRequest());
            request.LoadOptions = new string[] { "Currency" };
            request.Criteria = new CurrencyCriteria { CurrencyID = currencyId };

            var response = Client.GetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetCurrency: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.Currency);
        }
        public int GetTotalPageFromCurrency()
        {
            var request = PrepareRequest(new CurrencyRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromCurrency: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }

        #endregion

        #region Currency persistence

        public int AddCurrency(CurrencyModel currency)
        {
            var request = PrepareRequest(new CurrencyRequest());
            request.Action = "Create";

            request.Currency = Mapper.ToDataTransferObject(currency);

            var response = Client.SetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddCurrency: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateCurrency(CurrencyModel currency)
        {
            var request = PrepareRequest(new CurrencyRequest());
            request.Action = "Update";

            request.Currency = Mapper.ToDataTransferObject(currency);

            var response = Client.SetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateCurrency: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteCurrency(string currencyId)
        {
            var request = PrepareRequest(new CurrencyRequest());
            request.Action = "Delete";
            request.Criteria = new CurrencyCriteria { CurrencyID = currencyId };

            var response = Client.SetCurrencies(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteCurrency: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region Departments

        public DepartmentModel GetDepartment(string departmentId)
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.LoadOptions = new string[] { "Department" };
            request.Criteria = new DepartmentCriteria { DepartmentID = departmentId };

            var response = Client.GetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDepartment: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.Department);
        }

        public IList<DepartmentModel> GetDepartmentsByBranch()
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.LoadOptions = new string[] { "Departments", "ByBranch" };
            //request.Criteria = new DepartmentCriteria { DepartmentID = departmentId };

            var response = Client.GetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDepartmentsByBranch: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Departments);
        }
        public IList<DepartmentModel> GetDepartmentsActiveByBranch()
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.LoadOptions = new string[] { "Departments", "ActiveByBranch" };
            request.Criteria = new DepartmentCriteria { IsActive = true };

            var response = Client.GetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetDepartmentsActiveByBranch: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.Departments);
        }

        #endregion

        #region Department persistence

        public int AddDepartment(DepartmentModel department)
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.Action = "Create";

            department.RestaurantId = RestaurantID;
            request.Department = Mapper.ToDataTransferObject(department);

            var response = Client.SetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddDepartment: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateDepartment(DepartmentModel department)
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.Action = "Update";

            department.RestaurantId = RestaurantID;
            request.Department = Mapper.ToDataTransferObject(department);

            var response = Client.SetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateDepartment: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteDepartment(string departmentId)
        {
            var request = PrepareRequest(new DepartmentRequest());
            request.Action = "Delete";
            request.Criteria = new DepartmentCriteria { DepartmentID = departmentId };

            var response = Client.SetDepartments(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteDepartment: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region TimeSheetSign

        public IList<TimeSheetSignModel> GetTimeSheetSigns()
        {
            var request = PrepareRequest(new TimeSheetSignRequest());

            request.LoadOptions = new string[] { "TimeSheetSigns" };
            var response = Client.GetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTimeSheetSigns: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.TimeSheetSigns);
        }
        public IList<TimeSheetSignModel> GetTimeSheetSignsActive()
        {
            var request = PrepareRequest(new TimeSheetSignRequest());

            request.LoadOptions = new string[] { "TimeSheetSigns", "Active" };
            var response = Client.GetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTimeSheetSignsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.TimeSheetSigns);
        }
        public IList<TimeSheetSignModel> GetTimeSheetSignPaged(int currentPage)
        {
            var request = PrepareRequest(new TimeSheetSignRequest());

            request.LoadOptions = new string[] { "TimeSheetSigns", "ByPage" };
            request.Criteria = new TimeSheetSignCriteria { CurrentPage = currentPage };

            var response = Client.GetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTimeSheetSignPaged: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.TimeSheetSigns);
        }
        public int GetTotalPageFromTimeSheetSign()
        {
            var request = PrepareRequest(new TimeSheetSignRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromTimeSheetSign: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }
        public TimeSheetSignModel GetTimeSheetSign(string timeSheetSignId)
        {
            var request = PrepareRequest(new TimeSheetSignRequest());
            request.LoadOptions = new string[] { "TimeSheetSign" };
            request.Criteria = new TimeSheetSignCriteria { TimeSheetSignID = timeSheetSignId };

            var response = Client.GetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTimeSheetSign: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.TimeSheetSign);
        }

        #endregion

        #region TimeSheetSign persistence

        public int AddTimeSheetSign(TimeSheetSignModel timeSheetSign)
        {
            var request = PrepareRequest(new TimeSheetSignRequest());
            request.Action = "Create";

            request.TimeSheetSign = Mapper.ToDataTransferObject(timeSheetSign);

            var response = Client.SetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddTimeSheetSign: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateTimeSheetSign(TimeSheetSignModel timeSheetSign)
        {
            var request = PrepareRequest(new TimeSheetSignRequest());
            request.Action = "Update";

            request.TimeSheetSign = Mapper.ToDataTransferObject(timeSheetSign);

            var response = Client.SetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateTimeSheetSign: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteTimeSheetSign(string timeSheetSignId)
        {
            var request = PrepareRequest(new TimeSheetSignRequest());
            request.Action = "Delete";
            request.Criteria = new TimeSheetSignCriteria { TimeSheetSignID = timeSheetSignId };

            var response = Client.SetTimeSheetSigns(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteTimeSheetSign: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region ShipMethods

        public IList<ShipMethodModel> GetShipMethods()
        {
            var request = PrepareRequest(new ShipMethodRequest());

            request.LoadOptions = new string[] { "ShipMethods" };
            var response = Client.GetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetShipMethods: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObjects(response.ShipMethods);
        }
        public ShipMethodModel GetShipMethod(string shipMethodId)
        {
            var request = PrepareRequest(new ShipMethodRequest());
            request.LoadOptions = new string[] { "ShipMethod" };
            request.Criteria = new ShipMethodCriteria { ShipMethodID = shipMethodId };

            var response = Client.GetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetShipMethod: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.ShipMethod);
        }
        public IList<ShipMethodModel> GetShipMethodsActive()
        {
            var request = PrepareRequest(new ShipMethodRequest());

            request.LoadOptions = new string[] { "ShipMethods", "Active" };
            var response = Client.GetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetShipMethodsByIsActive: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.ShipMethods);
        }
        public IList<ShipMethodModel> GetShipMethodsByPage(int currentPage)
        {
            var request = PrepareRequest(new ShipMethodRequest());

            request.LoadOptions = new string[] { "ShipMethods", "ByPage" };
            request.Criteria = new ShipMethodCriteria { CurrentPage = currentPage };

            var response = Client.GetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetShipMethodsByPage: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.ShipMethods);
        }
        public int GetTotalPageFromShipMethod()
        {
            var request = PrepareRequest(new ShipMethodRequest());

            request.LoadOptions = new string[] { "TotalPage" };
            var response = Client.GetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromShipMethod: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.TotalPage;
        }

        #endregion

        #region ShipMethod persistence

        public int AddShipMethod(ShipMethodModel shipMethod)
        {
            var request = PrepareRequest(new ShipMethodRequest());
            request.Action = "Create";

            request.ShipMethod = Mapper.ToDataTransferObject(shipMethod);

            var response = Client.SetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("ShipMethodModel: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int UpdateShipMethod(ShipMethodModel shipMethod)
        {
            var request = PrepareRequest(new ShipMethodRequest());
            request.Action = "Update";

            request.ShipMethod = Mapper.ToDataTransferObject(shipMethod);

            var response = Client.SetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateShipMethod: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }
        public int DeleteShipMethod(string shipMethodId)
        {
            var request = PrepareRequest(new ShipMethodRequest());
            request.Action = "Delete";
            request.Criteria = new ShipMethodCriteria { ShipMethodID = shipMethodId };

            var response = Client.SetShipMethods(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("DeleteShipMethod: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region AutoID

        public AutoIDModel GetAutoID(string autoId)
        {
            var request = PrepareRequest(new AutoIDRequest());
            request.Criteria = new AutoIDCriteria { AutoID = autoId };

            var response = Client.GetAutoIDs(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAutoID: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.AutoID);
        }
        public AutoIDModel GetAutoIDByRefType(int refType)
        {
            var request = PrepareRequest(new AutoIDRequest());
            request.LoadOptions = new string[] { "AutoID", "RefTypeId" };
            request.Criteria = new AutoIDCriteria { RefTypeID = refType };

            var response = Client.GetAutoIDs(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetAutoIDByRefType: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return Mapper.FromDataTransferObject(response.AutoID);
        }
        public int UpdateAutoID(AutoIDModel autoId)
        {
            var request = PrepareRequest(new AutoIDRequest());
            request.Action = "Update";

            request.AutoID = Mapper.ToDataTransferObject(autoId);

            var response = Client.SetAutoIDs(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("UpdateAutoID: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion

        #region InwardOutward

        public IList<InwardOutwardModel> GetInwardOutwardsByBranch(int refType, int currentPage, bool isMaterial)
        {
            var request = PrepareRequest(new InwardOutwardRequest());

            request.LoadOptions = new string[] { "InwardOutwards", "ByPageAndBranch", "RefType" };
            request.Criteria = new InwardOutwardCriteria { CurrentPage = currentPage, RefType = refType, IsMaterial = isMaterial };

            var response = Client.GetInwardOutwards(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInwardOutwardsByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObjects(response.InwardOutwards);
        }
        public InwardOutwardModel GetInwardOutwardModel(string refId)
        {
            var request = PrepareRequest(new InwardOutwardRequest());

            request.LoadOptions = new string[] { "InwardOutward", "InwardOutwardDetails" };
            request.Criteria = new InwardOutwardCriteria { RefID = refId };

            var response = Client.GetInwardOutwards(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetInwardOutwardModel: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return Mapper.FromDataTransferObject(response.InwardOutward, response.InwardOutwardDetails);
        }
        public int GetTotalPageFromInwardOutwardByBranch(int refType, bool isMaterial)
        {
            var request = PrepareRequest(new InwardOutwardRequest());

            request.LoadOptions = new string[] { "TotalPage", "ByBranch", "RefType" };
            request.Criteria = new InwardOutwardCriteria { RefType = refType, IsMaterial = isMaterial };

            var response = Client.GetInwardOutwards(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("GetTotalPageFromInwardOutwardByBranch: RequestId và CorrelationId không trùng khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);
            return response.TotalPage;
        }

        #endregion

        #region InwardOutward persistence

        public int AddInwardOutward(InwardOutwardModel inwardOutward, string refTypeName)
        {
            var request = PrepareRequest(new InwardOutwardRequest());
            request.LoadOptions = new string[] { "InwardOutwardDetails" };
            request.Criteria = new InwardOutwardCriteria { RefType = inwardOutward.RefType };
            request.Action = "Create";

            inwardOutward.RestaurantID = RestaurantID;
            inwardOutward.RefID = Guid.NewGuid().ToString();

            for (int i = 0; i < inwardOutward.InwardOutwardDetails.Count; i++)
            {
                inwardOutward.InwardOutwardDetails[i].RefID = inwardOutward.RefID;
                inwardOutward.InwardOutwardDetails[i].RefDetailID = Guid.NewGuid().ToString();
            }

            request.Criteria = new InwardOutwardCriteria
            {
                InwardOutwardDetails = Mapper.ToDataTransferObjects(inwardOutward.InwardOutwardDetails),
                InventoryLedgers = Mapper.ToDataTransferObjects(ModelHelper.AddInventoryLedgerModel(inwardOutward, refTypeName)),
                GeneralLedgers = Mapper.ToDataTransferObjects(ModelHelper.AddGeneralLedgerModel(inwardOutward))
            };
            request.InwardOutward = Mapper.ToDataTransferObject(inwardOutward);

            var response = Client.SetInwardOutwards(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddInwardOutward: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        public int UpdateInwardOutward(InwardOutwardModel inwardOutward, string refTypeName)
        {
            var request = PrepareRequest(new InwardOutwardRequest());
            request.LoadOptions = new string[] { "InwardOutwardDetails" };
            request.Action = "Update";

            inwardOutward.RestaurantID = RestaurantID;

            for (int i = 0; i < inwardOutward.InwardOutwardDetails.Count; i++)
            {
                inwardOutward.InwardOutwardDetails[i].RefID = inwardOutward.RefID;
                inwardOutward.InwardOutwardDetails[i].RefDetailID = Guid.NewGuid().ToString();
            }

            request.Criteria = new InwardOutwardCriteria
            {
                InwardOutwardDetails = Mapper.ToDataTransferObjects(inwardOutward.InwardOutwardDetails),
                InventoryLedgers = Mapper.ToDataTransferObjects(ModelHelper.AddInventoryLedgerModel(inwardOutward, refTypeName)),
                GeneralLedgers = Mapper.ToDataTransferObjects(ModelHelper.AddGeneralLedgerModel(inwardOutward))
            };
            request.InwardOutward = Mapper.ToDataTransferObject(inwardOutward);

            var response = Client.SetInwardOutwards(request);

            if (response.CorrelationId != request.RequestId)
                throw new ApplicationException("AddInwardOutward: RequestId và CorrelationId không khớp.");

            if (response.Acknowledge != AcknowledgeType.Success)
                throw new ApplicationException(response.Message);

            return response.RowsAffected;
        }

        #endregion
    }
}